package com.csjbot.alicecontrolserver;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.text.TextUtils;

import com.csjbot.alicecontrolserver.Events.ServerEvent;
import com.csjbot.alicecontrolserver.server.MobileServer;
import com.csjbot.alicecontrolserver.server.handler.MessageRecInterface;
import com.csjbot.alicecontrolserver.server.handler.MessageServerHandler;
import com.csjbot.alicecontrolserver.tts.ISpeechSpeak;
import com.csjbot.alicecontrolserver.tts.SpeechFactory;
import com.csjbot.cosclient.CosClientAgent;
import com.csjbot.cosclient.constant.ClientConstant;
import com.csjbot.cosclient.entity.CommonPacket;
import com.csjbot.cosclient.entity.MessagePacket;
import com.csjbot.cosclient.listener.ClientEvent;
import com.csjbot.cosclient.listener.EventListener;
import com.csjbot.cosclient.utils.CosLogger;
import com.orhanobut.logger.Logger;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.Locale;

public class ServerService extends Service implements MessageRecInterface, EventListener {
    private MobileServer server;
    private EventBus eventBus;
    /* 语音合成类 */
    private ISpeechSpeak speechSpeak;
    private CosClientAgent clientAgent;
    private boolean isDancing = false;

    public ServerService() {

    }

    @Override
    public void onCreate() {
        super.onCreate();
        server = MobileServer.getInstance();
        if (eventBus == null) {
            eventBus = EventBus.getDefault();
        }
        clientAgent = CosClientAgent.createRosClientAgent(this, true);
        MessageServerHandler.setMessageRecInterface(this);

        if (clientAgent.isConnected()) {
            clientAgent.disConnect();
        }

        speechSpeak = SpeechFactory.createSpeech(this, SpeechFactory.SpeechType.IFLY);

        clientAgent.connect(ConnectConstants.serverIp, ConnectConstants.serverPort);

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void messageRec(String msg) {
        eventBus.post(new ServerEvent(ServerEvent.MESSAGE_COMMING, msg));
        if (TextUtils.isEmpty(msg)) return;

        try {
            JSONObject root = new JSONObject(msg);

            if (root.has("msg_id")) {
                String msg_id = root.getString("msg_id");
                if (msg_id.equals("USER_SPEECH")) {
                    speechSpeak.startSpeaking(root.getString("content"), null);
                } else if (msg_id.equals("USER_DANCE_START")) {
                    if (!isDancing) {
                        startDance();
                    }
                } else {
                    sendMessageToClient(msg);
                }
            }

        } catch (JSONException e) {
            Logger.e("Error Json " + msg);
            e.printStackTrace();
        }


    }


    private void sendMessageToClient(String msg) {
        try {
            MessagePacket packet = new CommonPacket(msg.getBytes());
            Logger.i(msg);
            clientAgent.sendMessage(packet);
        } catch (Exception e) {
            CosLogger.error("BaseClientReq:sendReq:e:" + e.toString());
        }
    }


    // 肢体部位
    public static class BodyPart {
        // 1重置
        public static final int RESET = 1;
        // 2头部关节
        public static final int HEAD = 2;
        // 3左大臂关节
        public static final int LEFT_ARM = 3;
        // 4右大臂关节
        public static final int RIGHT_ARM = 4;
        // 5双大臂关节
        public static final int DOUBLE_ARM = 5;
        // 6左小臂关节
        public static final int LEFT_FOREARM = 6;
        // 7右小臂关节
        public static final int RIGHT_FOREARM = 7;
        // 8双小臂关节
        public static final int DOUBLE_FOREARM = 8;
        // 腰部关节
        public static final int WAIST = 9;
    }


    // 动作
    public static class BodyAction {
        // 1无动作
        public static final int NONE = 1;
        // 2左转上
        public static final int LEFT_UP = 2;
        // 3右转下
        public static final int RIGHT_DOWN = 3;

        /**
         * 注意：action的4、5、6、7、8仅对头部电机有用。
         */

        // 4左右转
        public static final int LEFT_THEN_RIGHT = 4;
        // 5上转
        public static final int UP = 5;
        // 6下转
        public static final int DOWN = 6;
        // 7上下转
        public static final int UP_AND_DOWN = 7;
        // 上下停止
        public static final int HEAD_UP_AND_DOWN_STOP = 8;
        // 开始摆手
        public static final String ROBOT_ARM_LOOP_START_REQ = "ROBOT_ARM_LOOP_START_REQ";
        // 停止摆手
        public static final String ROBOT_ARM_LOOP_STOP_REQ = "ROBOT_ARM_LOOP_STOP_REQ";
    }


    private String upLeftHand = String.format(Locale.getDefault(),
            "{\"msg_id\":\"ROBOT_BODY_CTRL_CMD\",\"body_part\":%d,\"action\":%d}", BodyPart.LEFT_ARM, BodyAction.LEFT_UP);
    private String downLeftHand = String.format(Locale.getDefault(),
            "{\"msg_id\":\"ROBOT_BODY_CTRL_CMD\",\"body_part\":%d,\"action\":%d}", BodyPart.LEFT_ARM, BodyAction.RIGHT_DOWN);
    private String upRightHand = String.format(Locale.getDefault(),
            "{\"msg_id\":\"ROBOT_BODY_CTRL_CMD\",\"body_part\":%d,\"action\":%d}", BodyPart.RIGHT_ARM, BodyAction.LEFT_UP);
    private String downRightHand = String.format(Locale.getDefault(),
            "{\"msg_id\":\"ROBOT_BODY_CTRL_CMD\",\"body_part\":%d,\"action\":%d}", BodyPart.RIGHT_ARM, BodyAction.RIGHT_DOWN);
    private String diantou = String.format(Locale.getDefault(),
            "{\"msg_id\":\"ROBOT_BODY_CTRL_CMD\",\"body_part\":%d,\"action\":%d}", BodyPart.HEAD, BodyAction.UP_AND_DOWN);
    private String yaotou = String.format(Locale.getDefault(),
            "{\"msg_id\":\"ROBOT_BODY_CTRL_CMD\",\"body_part\":%d,\"action\":%d}", BodyPart.HEAD, BodyAction.LEFT_THEN_RIGHT);
    private String rightTurn30 = "{\"msg_id\":\"NAVI_GO_ROTATION_REQ\",\"rotation\":-30}";
    private String leftTurn30 = "{\"msg_id\":\"NAVI_GO_ROTATION_REQ\",\"rotation\":30}";

    private String rightTurn45 = "{\"msg_id\":\"NAVI_GO_ROTATION_REQ\",\"rotation\":-30}";
    private String leftTurn45 = "{\"msg_id\":\"NAVI_GO_ROTATION_REQ\",\"rotation\":30}";

    private String rightTurnDegree(int degree) {
        return String.format(Locale.getDefault(), "{\"msg_id\":\"NAVI_GO_ROTATION_REQ\",\"rotation\":-%d}", degree);
    }

    private String leftTurnDegree(int degree) {
        return String.format(Locale.getDefault(), "{\"msg_id\":\"NAVI_GO_ROTATION_REQ\",\"rotation\":%d}", degree);
    }


    private String rightTurn90 = "{\"msg_id\":\"NAVI_GO_ROTATION_REQ\",\"rotation\":-90}";
    private String leftTurn90 = "{\"msg_id\":\"NAVI_GO_ROTATION_REQ\",\"rotation\":90}";

    boolean test = true;
    boolean step1 = true;
    boolean step2 = true;
    boolean step3 = true;
    boolean step4 = true;

    private void startDance() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                isDancing = true;

                if (step1) {
                    // 抬左手
                    sendMessageToClient(upLeftHand);

                    // 抬右手
                    try {
                        Thread.sleep(1200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(upRightHand);

                    // 左转 + 放右手
                    try {
                        Thread.sleep(1200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(leftTurnDegree(45));

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(downRightHand);

                    // 右转 + 抬右手
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(rightTurnDegree(45));

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(upRightHand);

                    // 右转 + 放左手

                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(rightTurnDegree(45));

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(downLeftHand);

                    // 左转 + 抬左手

                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(leftTurnDegree(45));

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(upLeftHand);

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(diantou);
                    sendMessageToClient(yaotou);


                    sendMessageToClient(downLeftHand);
                    sendMessageToClient(downRightHand);
                }


                // 转身
                if (step2) {
                    int cnt = 0;
                    for (; cnt < 1; cnt++) {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        sendMessageToClient(rightTurnDegree(45));

                        sendMessageToClient(diantou);
                        sendMessageToClient(yaotou);


                        sendMessageToClient(upLeftHand);
                        try {
                            Thread.sleep(1200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        sendMessageToClient(downLeftHand);

                        try {
                            Thread.sleep(1200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        sendMessageToClient(upRightHand);

                        try {
                            Thread.sleep(1200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        sendMessageToClient(downRightHand);
//===========================================================================
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        sendMessageToClient(leftTurnDegree(45));

                        sendMessageToClient(diantou);
                        sendMessageToClient(yaotou);


                        sendMessageToClient(upLeftHand);
                        try {
                            Thread.sleep(1200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        sendMessageToClient(downLeftHand);

                        try {
                            Thread.sleep(1200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        sendMessageToClient(upRightHand);

                        try {
                            Thread.sleep(1200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        sendMessageToClient(downRightHand);
//===========================================================================
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        sendMessageToClient(leftTurnDegree(45));

                        sendMessageToClient(diantou);
                        sendMessageToClient(yaotou);


                        sendMessageToClient(upLeftHand);
                        try {
                            Thread.sleep(1200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        sendMessageToClient(downLeftHand);

                        try {
                            Thread.sleep(1200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        sendMessageToClient(upRightHand);

                        try {
                            Thread.sleep(1200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        sendMessageToClient(downRightHand);
                    }
//===========================================================================
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(rightTurnDegree(45));

                    sendMessageToClient(diantou);
                    sendMessageToClient(yaotou);


                    sendMessageToClient(upLeftHand);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(downLeftHand);

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(upRightHand);

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(downRightHand);


                    /*****
                     *  第二次
                     */


                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(rightTurnDegree(45));

                    sendMessageToClient(diantou);
                    sendMessageToClient(yaotou);


                    sendMessageToClient(upLeftHand);
                    try {
                        Thread.sleep(1200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(downLeftHand);

                    try {
                        Thread.sleep(1200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(upRightHand);

                    try {
                        Thread.sleep(1200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(downRightHand);
//===========================================================================
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(leftTurnDegree(45));

                    sendMessageToClient(diantou);
                    sendMessageToClient(yaotou);


                    sendMessageToClient(upLeftHand);
                    try {
                        Thread.sleep(1200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(downLeftHand);

                    try {
                        Thread.sleep(1200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(upRightHand);

                    try {
                        Thread.sleep(1200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(downRightHand);
//===========================================================================
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(leftTurnDegree(45));

                    sendMessageToClient(diantou);
                    sendMessageToClient(yaotou);


                    sendMessageToClient(upLeftHand);
                    try {
                        Thread.sleep(1200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(downLeftHand);

                    try {
                        Thread.sleep(1200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(upRightHand);

                    try {
                        Thread.sleep(1200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    sendMessageToClient(downRightHand);
                }
//===========================================================================
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sendMessageToClient(rightTurnDegree(45));

                sendMessageToClient(diantou);
                sendMessageToClient(yaotou);


                sendMessageToClient(upLeftHand);
                try {
                    Thread.sleep(1200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sendMessageToClient(downLeftHand);

                try {
                    Thread.sleep(1200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sendMessageToClient(upRightHand);

                try {
                    Thread.sleep(1200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sendMessageToClient(downRightHand);


                isDancing = false;
            }
        }).start();
    }



    /**
     * 接受底层消息.并分发下去
     *
     * @param event
     */
    @Override
    public void onEvent(ClientEvent event) {
        switch (event.eventType) {
            case ClientConstant.EVENT_RECONNECTED:
            case ClientConstant.EVENT_CONNECT_SUCCESS:
                eventBus.post(new ServerEvent(ServerEvent.MESSAGE_COMMING, "EVENT_CONNECT_SUCCESS"));
//                startDance();
                break;
            case ClientConstant.EVENT_CONNECT_FAILD:
                eventBus.post(new ServerEvent(ServerEvent.MESSAGE_COMMING, ClientConstant.EVENT_CONNECT_FAILD));
                break;
            case ClientConstant.EVENT_CONNECT_TIME_OUT:
                eventBus.post(new ServerEvent(ServerEvent.MESSAGE_COMMING, ClientConstant.EVENT_CONNECT_TIME_OUT));
                break;
            case ClientConstant.SEND_FAILED:
                break;
            case ClientConstant.EVENT_DISCONNET:
                eventBus.post(new ServerEvent(ServerEvent.MESSAGE_COMMING, ClientConstant.EVENT_DISCONNET));
                break;
            case ClientConstant.EVENT_PACKET:
                MessagePacket packet = (MessagePacket) event.data;
                CosLogger.warn("rec packet");
                CosLogger.warn(((CommonPacket) packet).getContentJson());
                server.sendMsg(((CommonPacket) packet).getContentJson());
                break;
            default:
                break;
        }
    }
}
